import { Model, Effect } from 'dva';
import { Reducer } from 'redux';
import { BiStatus } from '@/common/type/BiStatus';
import { add, remove, get, list, update } from '@/services/productCategory';

export interface ProductCategory {
  id: number;
  parentId?: number;
  name: string;
  level: number;
  productCount: number;
  productUnit: string;
  navStatus: BiStatus;
  showStatus: BiStatus;
  sort: number;
  icon?: string;
  keywords?: string;
  description?: string;
  children?: ProductCategory[];
}

export interface CategoryModelState {
  categories: ProductCategory[];
  category?: ProductCategory;
}

export interface CategoryModelType extends Model {
  namespace: 'productCategory';
  state: CategoryModelState;
  effects: {
    query: Effect;
    queryOne: Effect;
    add: Effect;
    remove: Effect;
    update: Effect;
  };
  reducers: {
    refresh: Reducer<CategoryModelState>;
    refreshOne: Reducer<CategoryModelState>;
  };
}

const BrandModel: CategoryModelType = {
  namespace: 'productCategory',
  state: {
    categories: [],
  },

  reducers: {
    refresh(state, action) {
      return {
        ...state,
        categories: action.categories,
      };
    },
    refreshOne(state, action) {
      return {
        ...state!,
        category: action.category,
      };
    },
  },

  effects: {
    *query({ payload }, { call, put }) {
      const response = yield call(list);
      yield put({
        type: 'refresh',
        categories: response,
      });
    },
    *queryOne({ id }, { call, put }) {
      const response = yield call(get, id);
      yield put({
        type: 'refreshOne',
        category: response,
      });
    },
    *add({ payload, callback }, { call, put }) {
      const formData = new FormData();
      for (const key of Object.keys(payload)) {
        if (key !== 'icon') {
          formData.append(key, payload[key]);
        } else if (payload[key]) {
          formData.append(
            'iconImg',
            payload[key][0].originFileObj,
            payload[key][0].originFileObj.name,
          );
        }
      }
      yield call(add, formData);
      yield put({
        type: 'query',
      });
      callback();
    },
    *update({ payload, callback }, { call, put }) {
      yield call(update, payload);
      if (callback) {
        callback();
      }
    },
    *remove({ payload }, { call, put }) {
      yield call(remove, payload);
      yield put({
        type: 'query',
      });
    },
  },

  subscriptions: {
    setup({ dispatch, history }) {
      history.listen(({ pathname }) => {
        if (pathname.startsWith('/product')) {
          dispatch({
            type: 'query',
          });
        }
      });
      history.listen(({ pathname, query }) => {
        if (pathname.startsWith('/product/category/add')) {
          if (query && query.id) {
            dispatch({
              type: 'queryOne',
              id: query.id,
            });
          } else {
            dispatch({
              type: 'refreshOne',
              category: undefined,
            });
          }
        }
      });
    },
  },
};

export default BrandModel;
